using System;
using System.Collections.Generic;
using OracleInternal.Common;
using OracleInternal.ServiceObjects;

namespace OracleInternal.TTC.Accessors
{
	internal class TTCVarcharAccessor : Accessor
	{
		internal TTCVarcharAccessor(ColumnDescribeInfo colMetaData, MarshallingEngine marshallingEngine, bool bForBind)
			: base(colMetaData, marshallingEngine, bForBind)
		{
			if (!bForBind)
			{
				InitForDataAccess(colMetaData.m_maxLength);
			}
		}

		internal override byte[] GetByteRepresentation(int currentRow)
		{
			throw new NotSupportedException();
		}

		internal override string GetString(int currentRow, byte charSetForm, char[] charArrayFromPooler)
		{
			string result = null;
			int num = m_totalLengthOfData[currentRow];
			if (num > 0)
			{
				List<ArraySegment<byte>> list = m_RowDataSegments[currentRow];
				if (list != null)
				{
					result = ((charSetForm == 2) ? m_marshallingEngine.m_nCharSetConv.ConvertBytesToString(list, 0, num, charArrayFromPooler) : m_marshallingEngine.m_dbCharSetConv.ConvertBytesToString(list, 0, num, charArrayFromPooler));
				}
			}
			return result;
		}

		internal override string GetString(DataUnmarshaller dataUnmarshaller, int currentRow, int columnIndex)
		{
			return GetString(dataUnmarshaller, currentRow, columnIndex, 1);
		}

		internal override string GetString(DataUnmarshaller dataUnmarshaller, int currentRow, int columnIndex, byte charSetForm)
		{
			string result = null;
			int length = 0;
			try
			{
				dataUnmarshaller.StartAccumulatingColumnData(currentRow, columnIndex, m_colDataSegments);
				dataUnmarshaller.UnmarshalCLR_ScanOnly(int.MaxValue, ref length);
				if (length > 0)
				{
					char[] charArrayForConversion = dataUnmarshaller.m_charArrayForConversion;
					if (charSetForm != 2)
					{
						return m_marshallingEngine.m_dbCharSetConv.ConvertBytesToString(m_colDataSegments, 0, length, charArrayForConversion);
					}
					return m_marshallingEngine.m_nCharSetConv.ConvertBytesToString(m_colDataSegments, 0, length, charArrayForConversion);
				}
				return result;
			}
			finally
			{
				m_colDataSegments.Clear();
				dataUnmarshaller.m_bAccumulateByteSegments = false;
				dataUnmarshaller.m_dataSegments = null;
			}
		}

		internal int GetCharsFromBuffer(DataUnmarshaller dataUnmarshaller, int currentRow, int columnIndex, long fieldOffset, char[] buffer, int bufferOffset, int noOfCharsReqd, byte charSetForm)
		{
			int result = 0;
			int length = 0;
			try
			{
				dataUnmarshaller.StartAccumulatingColumnData(currentRow, columnIndex, m_colDataSegments);
				dataUnmarshaller.UnmarshalCLR_ScanOnly(int.MaxValue, ref length);
				if (length > 0)
				{
					int bytesOffset = (int)fieldOffset;
					result = noOfCharsReqd;
					if (charSetForm != 2)
					{
						if (m_marshallingEngine.m_dbCharSetConv.MaxBytesPerChar > 1 && fieldOffset > 0)
						{
							bytesOffset = m_marshallingEngine.m_dbCharSetConv.GetBytesOffset(m_colDataSegments, (int)fieldOffset);
						}
						m_marshallingEngine.m_dbCharSetConv.ConvertBytesToChars(m_colDataSegments, bytesOffset, length, buffer, bufferOffset, ref result);
						return result;
					}
					if (m_marshallingEngine.m_nCharSetConv.MaxBytesPerChar > 1 && fieldOffset > 0)
					{
						bytesOffset = m_marshallingEngine.m_nCharSetConv.GetBytesOffset(m_colDataSegments, (int)fieldOffset);
					}
					m_marshallingEngine.m_nCharSetConv.ConvertBytesToChars(m_colDataSegments, bytesOffset, length, buffer, bufferOffset, ref result);
					return result;
				}
				return result;
			}
			finally
			{
				m_colDataSegments.Clear();
				dataUnmarshaller.m_bAccumulateByteSegments = false;
				dataUnmarshaller.m_dataSegments = null;
			}
		}

		internal int GetCharLengthFromBuffer(DataUnmarshaller dataUnmarshaller, int currentRow, int columnIndex, long fieldOffset, byte charSetForm)
		{
			int result = 0;
			int length = 0;
			try
			{
				dataUnmarshaller.StartAccumulatingColumnData(currentRow, columnIndex, m_colDataSegments);
				dataUnmarshaller.UnmarshalCLR_ScanOnly(int.MaxValue, ref length);
				if (length > 0)
				{
					int bytesOffset = (int)fieldOffset;
					if (charSetForm != 2)
					{
						if (m_marshallingEngine.m_dbCharSetConv.MaxBytesPerChar > 1 && fieldOffset > 0)
						{
							bytesOffset = m_marshallingEngine.m_dbCharSetConv.GetBytesOffset(m_colDataSegments, (int)fieldOffset);
						}
						return m_marshallingEngine.m_dbCharSetConv.GetCharsLength(m_colDataSegments, bytesOffset, length);
					}
					if (m_marshallingEngine.m_nCharSetConv.MaxBytesPerChar > 1 && fieldOffset > 0)
					{
						bytesOffset = m_marshallingEngine.m_nCharSetConv.GetBytesOffset(m_colDataSegments, (int)fieldOffset);
					}
					return m_marshallingEngine.m_nCharSetConv.GetCharsLength(m_colDataSegments, bytesOffset, length);
				}
				return result;
			}
			finally
			{
				m_colDataSegments.Clear();
				dataUnmarshaller.m_bAccumulateByteSegments = false;
				dataUnmarshaller.m_dataSegments = null;
			}
		}
	}
}
